package com.logistics.utils.jwt;


import com.alibaba.fastjson.JSONObject;
import com.logistics.utils.configure.Configure;
import com.logistics.utils.tool.StringUtils;
import io.jsonwebtoken.*;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.lang.reflect.Field;
import java.util.Date;

@Component
public class JwtRegistry {

    @Autowired
    private Configure configure;

    /**
     * 创建 token
     * @param subject
     * @return
     */
    public String createToken(String subject){
        return createToken(subject, 0);
    }

    /**
     * 创建token
     * @param subject
     * @param time
     * @return
     */
    public String createToken(String subject, long time){
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey key = generalKey();
        JwtBuilder  builder = Jwts.builder().setId(configure.getToken().getId()).setIssuedAt(now)
                .setSubject(subject).signWith(SignatureAlgorithm.HS256, key);
        long tokenTime = time == 0 ? configure.getToken().getTime() : time;
        Date exp = new Date(nowMillis + tokenTime);
        builder.setExpiration(exp);
        return builder.compact();
    }


    /**
     * 生产key
     * @return
     */
    private SecretKey generalKey(){
        String jwtName = "JWT";
        String jwtSecret = configure.getToken().getSecret();
        String stringKey = jwtName + jwtSecret;
        byte[] encodeKey = Base64.decodeBase64(stringKey);
        return new SecretKeySpec(encodeKey, 0, encodeKey.length, "AES");
    }

    /**
     *
     * @param object
     * @return
     * @throws Exception
     */
    public String generalSubject(Object object) throws Exception {
        JSONObject json = new JSONObject();
        Class<?> cls = object.getClass();
        Field[] fields = cls.getDeclaredFields();
        Field[] arr = fields;
        int len = fields.length;
        for(int i = 0; i < len; i++) {
            Field field = arr[i];
            field.setAccessible(true);
            String key = field.getName();
            json.put(key, field.get(object));
        }

        return json.toString();
    }

    public Claims parseJWT(String jwt) throws ExpiredJwtException {
        SecretKey key = this.generalKey();
        Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(jwt).getBody();
        return claims;
    }

}
